package com.example.leepong;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.util.Log;
import android.view.SurfaceHolder;
import android.widget.Toast;

import com.example.leepong.Game.Engine;
import com.example.leepong.Game.Utils.PerfsMonitor;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by Ichigo on 02/03/14.
 */
public class GameLoop {
    private GameSurface _gameSurface;
    private Engine _engine;
    private SurfaceHolder _surfaceHolder;
    private ScheduledThreadPoolExecutor _mainTimer;
    private ScheduledFuture<?> _mainSchedule;

    public GameLoop(GameSurface surface) {
        _gameSurface = surface;
        _engine = _gameSurface.Engine;
        _surfaceHolder = _gameSurface.getHolder();
    }

    public void Launch(int ups) {

        long period = 1000 / ups;
        _mainTimer = new ScheduledThreadPoolExecutor(1);
        _mainSchedule = _mainTimer.scheduleAtFixedRate(new UpdateBallTask(), 0, period, TimeUnit.MILLISECONDS);
    }

    public void Stop() {
        if (_mainTimer != null)
            _mainTimer.shutdown();
    }


    class UpdateBallTask implements Runnable {

        public void run() {
            // double p = DetectMinPeriod();

            try {
                RunInternal();
            } catch (Exception ex) {

                HandleExceptions(ex);

                ex.printStackTrace();
                throw ex;
            }
        }

        private void RunInternal() {
            Update();
            Render();
        }
    }


    private void Update() {

        // update game state
        _engine.Update();

    }

    private void Render() {

        Canvas canvas = _surfaceHolder.lockCanvas();
        if (canvas == null)
            return;

        _gameSurface.DrawingManager.DoDraw(canvas);
        _surfaceHolder.unlockCanvasAndPost(canvas);
    }

    private void HandleExceptions(Exception ex) {
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw));
        String exceptionAsString = sw.toString();

        // prepare the alert box
        final AlertDialog.Builder alertBox = new AlertDialog.Builder(_gameSurface.getContext());

        // set the message to display
        alertBox.setMessage(exceptionAsString);

        // add a neutral button to the alert box and assign a click listener
        alertBox.setNeutralButton("Ok", new DialogInterface.OnClickListener() {

            // click listener on the alert box
            public void onClick(DialogInterface arg0, int arg1) {
                // the button was clicked
                Toast.makeText(_gameSurface.getContext(), "OK button clicked", Toast.LENGTH_LONG).show();
            }
        });
        _gameSurface.post(new Runnable() {
            @Override
            public void run() {
                // show it
                alertBox.show();
            }
        });
    }

}
